package model

import (
	"database/sql"
	"fmt"
	"github.com/jmoiron/sqlx"
	"time"
	"zimuzu_cvn_web_api/config"
	. "zimuzu_cvn_web_api/pkg/e"
)

const (
	LogSourceUsdtIn        = 101 //站外收款
	LogSourceUsdtInnerIn   = 102 //站内收款
	LogSourceUsdtSaleToken = 103 //出售令牌
	LogSourceUsdtFailBack  = 104 //转账失败返还
	LogSourceUsdtRebate    = 105 //返佣
	LogSourceUsdtOut       = 201 //站外转账
	LogSourceUsdtInnerOut  = 202 //站内转账
	LogSourceUsdtBuyToken  = 203 //购买令牌
	LogSourceUsdtFee       = 204 //转账手续费
)

type UsdtLogDB struct {
	Id               int64   `db:"id"`
	Uid              int64   `db:"uid"`
	Amount           float64 `db:"amount"`
	Balance          float64 `db:"balance"`
	RelateId         string  `db:"relate_id"`
	RelateTable      string  `db:"relate_table"`
	From             string  `db:"from"`
	To               string  `db:"to"`
	TxHash           string  `db:"txhash"`
	Source           int     `db:"source"`
	Status           int     `db:"status"`
	CreateTime       int64   `db:"create_time"`
	UpdateTime       int64   `db:"update_time"`
	Block            int64   `db:"block"`
	BlockConfirmTime int64   `db:"block_confirm_time"`
	SignString       string  `db:"sign_string"`
	SignVersion      string  `db:"sign_version"`
}

//插入记录
func AddUsdtLog(db sqlx.Execer, data UsdtLogDB) (id int64, err error) {
	data.TxHash = Trim(data.TxHash)
	data.CreateTime = time.Now().Unix()
	data.UpdateTime = time.Now().Unix()
	if data.Status == 0 {
		data.Status = 1
	}
	result, err := db.Exec("INSERT INTO usdt_log (uid,amount,balance,relate_id,relate_table,txhash,`from`,`to`,source,status,create_time,update_time,block,block_confirm_time,sign_string,sign_version) VALUES (?, ?, ?, ?, ?, if(? = '', null, ?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
		data.Uid, data.Amount, data.Balance, data.RelateId, data.RelateTable, data.TxHash, data.TxHash, data.From, data.To, data.Source, data.Status, data.CreateTime, data.UpdateTime, data.Block, data.BlockConfirmTime, data.SignString, data.SignVersion)
	if err != nil {
		Log("err", err)
		return 0, err
	}
	id, err = result.LastInsertId()
	if err != nil {
		Log("err", err)
		return 0, err
	}
	return id, nil
}

//修改记录：状态
func UpdateUsdtLogStatus(db sqlx.Execer, data UsdtLogDB) (err error) {
	data.UpdateTime = time.Now().Unix()
	_, err = db.Exec(`update usdt_log SET txhash = if(? = "", null, ?), status = ?, block = ?, block_confirm_time = ?, update_time = ? WHERE id = ?`,
		data.TxHash, data.TxHash, data.Status, data.Block, data.BlockConfirmTime, data.UpdateTime, data.Id)
	if err != nil {
		Log("info", err)
	}
	return err
}

//获取列表：转账中
func GetUsdtLogWaitList(db sqlx.Queryer) (qi []UsdtLogDB, err error) {
	err = sqlx.Select(db, &qi, "SELECT id,uid,amount,`from`,`to`,source,status,create_time FROM usdt_log where source = ? AND status = ? ORDER BY id ASC", LogSourceUsdtOut, DealStatusCheck)
	if err != nil {
		Log("err", err)
	}
	return qi, err
}

//获取列表：uid
func GetUsdtLogListByUid(db sqlx.Queryer, uid int64) (qi []CvnLogDb, err error) {
	err = sqlx.Select(db, &qi, "select id,uid,amount,balance,relate_id,relate_table,`from`,`to`,source,sign_string,sign_version from usdt_log where uid = ? order by id desc", uid)
	if err != nil {
		Log("err", err)
	}
	return qi, err
}

//获取单条记录
func GetUsdtLog(db sqlx.Queryer, id int64) (qi UsdtLogDB, err error) {
	err = sqlx.Get(db, &qi, "SELECT id,uid,amount,balance,relate_id,relate_table,`from`,`to`,IFNULL(txhash,'') as txhash,source,status,create_time,update_time,block,block_confirm_time,sign_string,sign_version FROM usdt_log WHERE id = ?", id)
	if err != nil {
		Log("err", err)
	}
	return qi, err
}

//获取最后一条日志签名
func GetLastUsdtLogSign(db sqlx.Queryer, uid int64) (sign DbSign, err error) {
	err = sqlx.Get(db, &sign, "select sign_string,sign_version from usdt_log where uid = ? order by id desc limit 1", uid)
	if err == sql.ErrNoRows {
		err = nil
	}
	if err != nil {
		Log("err", err)
	}
	return sign, err
}

//修改记录：签名
func UpdateUsdtLogSign(db sqlx.Execer, logid int64, signString, signVersion string) (err error) {
	_, err = db.Exec("update usdt_log set sign_string = ?, sign_version = ? where id = ?", signString, signVersion, logid)
	if err != nil {
		Log("err", err)
	}
	return err
}

//获取手续费
func GetUsdtLogCharge(db sqlx.Queryer, id int64) (charge float64, err error) {
	err = sqlx.Get(db, &charge, "SELECT amount FROM usdt_log WHERE relate_id = ? and source = ?", id, LogSourceUsdtFee)
	if err != nil {
		Log("err", err)
	}
	return charge, err
}

//TxHash是否存在
func ExistUsdtLogTxHash(db sqlx.Queryer, txHash string) (bool, error) {
	var count int
	err := sqlx.Get(db, &count, "SELECT count(*) FROM usdt_log WHERE txhash = ?", txHash)
	if err != nil {
		Log("err", err)
		return false, err
	}
	if count == 0 {
		return false, nil
	}
	return true, nil
}

//检查关联记录是否存在
func ExistUsdtLogRelated(db sqlx.Queryer, relateId string, source int) (bool, error) {
	var count int
	err := sqlx.Get(db, &count, "SELECT count(*) FROM usdt_log WHERE relate_id = ? and source = ?", relateId, source)
	if err != nil {
		Log("err", err)
		return false, err
	}
	if count == 0 {
		return false, nil
	}
	return true, nil
}

//查询某种来源的金额
func SumUsdtLogSource(db sqlx.Queryer, uid int64, source int, day int64) (sum float64, err error) {
	t := time.Now().Unix() - day*TimeFormatDay
	sqlStr := "SELECT IFNULL(sum(amount),0) as amount FROM usdt_log WHERE uid = ? "
	if source > 0 {
		sqlStr += fmt.Sprintf("and source = %d ", source)
	}
	if day > 0 {
		sqlStr += fmt.Sprintf("and create_time >= %d ", t)
	}
	err = sqlx.Get(db, &sum, sqlStr, uid)
	if err != nil {
		Log("err", err)
		return 0, err
	}
	return sum, err
}

//查询Usdt累计提现金额
func GetWithdrawTotalUsdt()(count float64, err error){
	err = sqlx.Get(config.C.DB.DB, &count, "select -sum(amount) from usdt_log where source = 201 and status = 1")
	if err != nil {
		Log("err", "查询累计提现信息失败:", err.Error())
	}
	return
}

//管理后台Usdt流水统计
func UsdtLogAdminStatistjcs(page, per int)(res []CvnLogAdminStatistjcsRes, err error){
	start :=  (page - 1) * per
	err = sqlx.Select(config.C.DB.DB, &res, "select FROM_UNIXTIME(l.create_time,'%Y-%m-%d') date, -sum(if(source=201,amount,0)) withdrawToday,sum(if(source=101,amount,0)) rechargeToday  ,-sum(if(source=201&&e.status=1,amount,0)) examineToday from usdt_log l  left JOIN usdt_examine e ON e.log_id = l.id and e.status = 1 where source = 101 or source = 201 GROUP BY FROM_UNIXTIME(l.create_time,'%Y-%m-%d') ORDER BY  l.create_time DESC limit ? , ?", start, per)
	if err != nil {
		Log("CvnLogAdminStatistjcs: ", err.Error())
	}
	return
}

type UsdtLogRechargeDaylyRes struct{
	Date string `db:"time" json:"time"`
	Amount float64 `json:"value" db:"value"`
}
//管理后台CVN流水统计
func UsdtLogRechargeDayly(page, per int)(res []UsdtLogRechargeDaylyRes, err error){
	start :=  (page - 1) * per
	err = sqlx.Select(config.C.DB.DB, &res, " select FROM_UNIXTIME(create_time,'%Y-%m-%d') time, sum(amount) value from usdt_log where status = 1 and source = 101 GROUP BY FROM_UNIXTIME(create_time,'%Y-%m-%d') ORDER BY  create_time DESC limit ? , ?", start, per)
	if err != nil {
		Log("CvnLogRechargeDayly: ", err.Error())
	}
	return
}
